/**
* 
* Task list manager
* Copyright (c) 2009 Ecole Centrale de Nantes IRCCyN  
* 
* see <a href="{@docRoot}/Documentation/kernelmessage.html"> for more information</a>
* 
* @author: Urunuela Richard
* @version 3.2
*/
package storm;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Vector;

import log.penalityTrace;

import org.jgraph.graph.DefaultGraphModel;
import org.jgraph.graph.GraphModel;

import programme.GUI.JData;
import storm.Data.Data;
import storm.Processors.Processor;
import storm.Tasks.Task;
/**
 * 
 * @author richard
 *
 */
public class TasksListeManager extends Entity implements ITaskListManager {
	private ArrayList listeTasks;
	private ArrayList listeCPU;
	private ArrayList listeData;
	public String name="TaskListeManager";

	/**
	 * 
	 */
	public TasksListeManager(){
		this.listeTasks= new ArrayList();
		this.listeCPU  	= new ArrayList();
		this.listeData = new ArrayList();
	}
	/* (non-Javadoc)
	 * @see storm.ITaskListManager#addTasks(storm.Tasks.Task)
	 */
	public void addTasks(Task T){
		this.listeTasks.add(T);
	}
	/* (non-Javadoc)
	 * @see storm.ITaskListManager#addData(storm.Data.Data)
	 */
	public void addData(Data T){
		this.listeData.add(T);
	}
	/* (non-Javadoc)
	 * @see storm.ITaskListManager#init()
	 */
	public void init(){
		debug_mess(" [ INIT TLM ] " , 10);
		Iterator i = this.listeTasks.iterator();
		/**
		 * Activation task
		 */
		while( i.hasNext()) {
			Task crt =(Task) i.next();
			if (crt.isunexisting){
				if ((crt.activationDate)  == 0){
					debug_mess("[Activate Task INIT]  " + crt + " " + this.Kernel.getTime() +  " " + crt.activationDate,10);
					crt.scheduler = this.Kernel.getScheduler(); //select scheduler 
					raiseActivate(crt,this.Kernel.getScheduler());
					if (crt.getpenality()>0) {
						this.Kernel.getLogs().addTrace(new penalityTrace(this.Kernel.getTime(),penalityTrace.Type.TASKINIT,""+ crt.getName() + " with activation penality value: " + crt.getpenality()));
					}
					
				}
			}
			
		}
		/**
		 * Block task if  data needing exist 
		 */
		i = this.listeData.iterator();
		while( i.hasNext()) {
			Data crt = (Data) i.next();
			if ((crt.getDestination().activationDate)  == 0){
					crt.raiseBlock(crt.getDestination());
			}
		}
	}
	/* (non-Javadoc)
	 * @see storm.ITaskListManager#onTick()
	 */
	public void onTick(){
		debug_mess("[EVT On tick Liste TASKS ] ",10);
		for (int k=0; k < listeTasks.size() ;k++)
		debug_mess(" [ DEBUG LISTE ] " + this.listeTasks.size()+ " task " + this.listeTasks.get(k) + "  "+((Task)this.listeTasks.get(k)).isready + ((Task)this.listeTasks.get(k)).iswaiting + ((Task)this.listeTasks.get(k)).isIsrunning() + ((Task)this.listeTasks.get(k)).isunexisting,10);
		Iterator i = this.listeTasks.iterator();
		while( i.hasNext()) {
			Task crt =(Task) i.next();
			/**
			 * Activate Task
			 */
			if (crt.isunexisting){
			if ((crt.activationDate-1)  == this.Kernel.getTime()){
				/*
				 * Activate 
				 */
				debug_mess("[Activate Task ]  " + crt + " " + this.Kernel.getTime() +  " " + crt.activationDate,10);
				
				crt.scheduler = this.Kernel.getScheduler(); 
				/**
				*select scheduler
				*/ 
				raiseActivate(crt,this.Kernel.getScheduler());
				
			}
			}
		}
		/**
		 * Block task if data exist
		 */
		i = this.listeData.iterator();
		while( i.hasNext()) {
			
			Data crt = (Data) i.next();
			if ((crt.getDestination().activationDate-1)  == this.Kernel.getTime()){
		//		System.out.println("BLOCK" +  crt.getDestination());
					crt.raiseBlock(crt.getDestination());
			}
		}
	}
	/* (non-Javadoc)
	 * @see storm.ITaskListManager#getProcessors()
	 */
	public ArrayList getProcessors(){
		debug_mess("[TLM give liste processeur ] " +this.listeCPU.size(),10); 
		return this.listeCPU;
	}
	/* (non-Javadoc)
	 * @see storm.ITaskListManager#getReadyTask()
	 */
	public ArrayList getReadyTask() {
		ArrayList res = new ArrayList();
		for (int i=0; i< this.listeTasks.size(); i++){
			Task crt = (Task) this.listeTasks.get(i);
			debug_mess("[Calc READY TASK ]"  + i + " on  " + this.listeTasks.size() + " " + crt + " REady " +crt.isready + " running " + crt.isIsrunning()+ " suspended " + crt.isunexisting + " waiting " + crt.iswaiting,10);
			if ((crt.isready)) res.add(crt);
		}
		return res;
	}
	/* (non-Javadoc)
	 * @see storm.ITaskListManager#addCPU(storm.Processors.Processor)
	 */
	public void addCPU(Processor P) {
		// TODO Auto-generated method stub
		this.listeCPU.add(P);
	}
	/* (non-Javadoc)
	 * @see storm.ITaskListManager#getName()
	 */
	public String getName(){
		return "TLM" ;
	}
	/* (non-Javadoc)
	 * @see storm.ITaskListManager#processingConstraint()
	 */
	public void processingConstraint() {
		/**
		 * data treatment
		 * if necessary change algorithm to unblock task
		 * and delay some unblock 
		 */
		Iterator i = this.listeData.iterator();
		while( i.hasNext()) {
			Data D = (Data) i.next();
			if (D.isProduite()) {
				this.debug_mess("[DATA UNBLOCK]  " + D ,10);
				if (!(D.getDestination().isunexisting)){
					
					if (D.getRate() ==  D.getCountBase()){
						D.raiseUnBlock(D.getDestination());
						D.setCountBase(1);
					}
					else 
					{
						D.setCountBase(D.getCountBase()+1);
					}
				}
				else {
					this.Kernel.showerror("[910] Products data for Task "+ D.getDestination().getName()    +" in unexisting state "  );
				}
				D.setProduite(false);
				D.getSource().setdataControlRunning(false);
			}
			else{
			if (D.isConsommer()) {
				this.debug_mess("[DATA BLOCK] " + D.getDestination().getdataControlRunning(),10);
				D.setConsommer(false);
					D.raiseBlock(D.getDestination());
				D.getDestination().setdataControlRunning(false);
				}
			}
		}
		
	}
	/* (non-Javadoc)
	 * @see storm.ITaskListManager#getWaitingTask()
	 */
	public ArrayList getWaitingTask() {
		
		ArrayList res = new ArrayList();
		  
		for (int i=0; i< this.listeTasks.size(); i++){
			
			Task crt = (Task) this.listeTasks.get(i);
			debug_mess("[Calc READY TASK ]"  + i + " on  " + this.listeTasks.size() + " " + crt + " REady " +crt.isready + " running " + crt.isIsrunning()+ " suspended " + crt.isunexisting + " waiting " + crt.iswaiting,10);
			if ((crt.iswaiting)) res.add(crt);
		}
		
		return res;
	}
/* (non-Javadoc)
 * @see storm.ITaskListManager#dataSetFactory(java.util.Vector, java.util.Vector)
 */
	public void dataSetFactory(Vector name2, Vector matrice_adjacence) {
		
		int i;
		Vector tmp=new Vector();
		int size = this.listeTasks.size()+ this.listeData.size();
		/**
		 * Add task 
		 */
		for (i=0; i < this.listeTasks.size();i++){
			Task T = (Task)this.listeTasks.get(i);
			name2.add(T.getName());
			matrice_adjacence.add(new int[size]);
			tmp.add(T);
			
		}
		for ( i=0; i < this.listeData.size();i++){
			Data D = (Data)this.listeData.get(i);
			name2.add(D.getName());
			matrice_adjacence.add(new int[size]);
			
		}

		for ( i=0; i <listeData.size() ;i++){
			int j,s = -1,d=-1;
			Data D = (Data)this.listeData.get(i);
			/**
			 * task source
			 */
			for (j=0;j<  tmp.size(); j++) {
				Task crt = (Task) tmp.get(j);
				if (crt == D.getSource()) s=j;
				if (crt == D.getDestination()) d=j;
			}
			
			int colonne[] = (int [])matrice_adjacence.get(s);
			colonne[listeTasks.size() + i] = 1;
			colonne= (int [])matrice_adjacence.get(listeTasks.size() + i);
			colonne[d] = 1;
		}
	}
	/* (non-Javadoc)
	 * @see storm.ITaskListManager#getALLProcessors()
	 */
	public ArrayList getALLProcessors() {
		// TODO Auto-generated method stub
		return this.listeCPU;
	}
	/* (non-Javadoc)
	 * @see storm.ITaskListManager#getALLTask()
	 */
	public ArrayList getALLTask() {
		return this.listeTasks;
		// TODO Auto-generated method stub
		
	}
	/* (non-Javadoc)
	 * @see storm.ITaskListManager#getDatas()
	 */
	public ArrayList getDatas() {
		// TODO Auto-generated method stub
		return this.listeData;
	}
/* (non-Javadoc)
 * @see storm.ITaskListManager#getTaskbyId(int)
 */
	public Task getTaskbyId(int num) {
		Task res = null;
		Iterator i = this.listeTasks.iterator();
		while (i.hasNext()){
			Task t = (Task)i.next();
			if (t.getId() == num) {
				res = t;
				break;
			}
		}
		// TODO Auto-generated method stub
		return res;
	}
/* (non-Javadoc)
 * @see storm.ITaskListManager#getProcessorsById(int)
 */
public Processor getProcessorsById(int numCpu) {
	// TODO Auto-generated method stub
	Processor CPU=null;
	Iterator i = this.listeCPU.iterator();
	while (i.hasNext()){
		Processor t = (Processor)i.next();
		if (t.getId() == numCpu) {
			CPU = t;
			break;
		}
	}
	
	
	
	return CPU;
}
	


}
